/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    uart_comm.c
  * @brief   串口通信库实现文件
  * @note    实现串口收发功能，支持中断接收和阻塞发送
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "uart_comm.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

/* USER CODE BEGIN Private typedef */

/* USER CODE END Private typedef */

/* USER CODE BEGIN Private variables */

/* 串口接收缓冲区 */
static uint8_t uart_rx_buffer[UART_RX_BUFFER_SIZE];

/* 串口发送缓冲区 */
static uint8_t uart_tx_buffer[UART_TX_BUFFER_SIZE];

/* 接收缓冲区读写指针 */
static volatile uint16_t rx_read_index = 0;
static volatile uint16_t rx_write_index = 0;

/* 发送缓冲区读写指针 */
static volatile uint16_t tx_read_index = 0;
static volatile uint16_t tx_write_index = 0;

/* 串口接收状态标志 */
static volatile uint8_t uart_rx_ready = 0;

/* 串口发送状态标志 */
static volatile uint8_t uart_tx_busy = 0;

/* USER CODE END Private variables */

/* USER CODE BEGIN Private function prototypes */

/**
 * @brief  计算缓冲区中的数据长度
 * @param  read_index: 读指针
 * @param  write_index: 写指针
 * @param  buffer_size: 缓冲区大小
 * @retval uint16_t: 数据长度
 */
static uint16_t UART_CalculateDataLength(uint16_t read_index, uint16_t write_index, uint16_t buffer_size);

/**
 * @brief  计算缓冲区中的可用空间
 * @param  read_index: 读指针
 * @param  write_index: 写指针
 * @param  buffer_size: 缓冲区大小
 * @retval uint16_t: 可用空间大小
 */
static uint16_t UART_CalculateFreeSpace(uint16_t read_index, uint16_t write_index, uint16_t buffer_size);

/* USER CODE END Private function prototypes */

/* USER CODE BEGIN 0 */

/**
 * @brief  串口通信初始化
 * @param  None
 * @retval None
 * @note   初始化串口接收缓冲区，启动接收中断
 */
void UART_Comm_Init(void)
{
    /* 清空接收缓冲区 */
    memset(uart_rx_buffer, 0, UART_RX_BUFFER_SIZE);
    
    /* 清空发送缓冲区 */
    memset(uart_tx_buffer, 0, UART_TX_BUFFER_SIZE);
    
    /* 初始化读写指针 */
    rx_read_index = 0;
    rx_write_index = 0;
    tx_read_index = 0;
    tx_write_index = 0;
    
    /* 初始化状态标志 */
    uart_rx_ready = 0;
    uart_tx_busy = 0;
    
    /* 启动串口接收中断 */
    HAL_UART_Receive_IT(&huart1, &uart_rx_buffer[rx_write_index], 1);
}

/**
 * @brief  串口发送字符串
 * @param  str: 要发送的字符串
 * @retval UART_TX_Status_t: 发送状态
 * @note   阻塞式发送，会等待发送完成
 */
UART_TX_Status_t UART_SendString(const char* str)
{
    if (str == NULL) {
        return UART_TX_ERROR;
    }
    
    return UART_SendData((uint8_t*)str, strlen(str));
}

/**
 * @brief  串口发送数据
 * @param  data: 要发送的数据指针
 * @param  size: 数据长度
 * @retval UART_TX_Status_t: 发送状态
 * @note   阻塞式发送，会等待发送完成
 */
UART_TX_Status_t UART_SendData(const uint8_t* data, uint16_t size)
{
    uint32_t start_time;
    HAL_StatusTypeDef status;
    
    if (data == NULL || size == 0) {
        return UART_TX_ERROR;
    }
    
    /* 检查数据长度是否超过发送缓冲区大小 */
    if (size > UART_TX_BUFFER_SIZE) {
        return UART_TX_ERROR;
    }
    
    /* 等待之前的发送完成 */
    start_time = HAL_GetTick();
    while (uart_tx_busy) {
        if (HAL_GetTick() - start_time > UART_TX_TIMEOUT) {
            return UART_TX_TIMEOUT_ERR;
        }
    }
    
    /* 设置发送忙标志 */
    uart_tx_busy = 1;
    
    /* 复制数据到发送缓冲区 */
    memcpy(uart_tx_buffer, data, size);
    tx_write_index = size;
    tx_read_index = 0;
    
    /* 启动发送 */
    status = HAL_UART_Transmit_IT(&huart1, (uint8_t*)uart_tx_buffer, size);
    
    if (status != HAL_OK) {
        uart_tx_busy = 0;
        return UART_TX_ERROR;
    }
    
    /* 等待发送完成 */
    start_time = HAL_GetTick();
    while (uart_tx_busy) {
        if (HAL_GetTick() - start_time > UART_TX_TIMEOUT) {
            uart_tx_busy = 0;
            return UART_TX_TIMEOUT_ERR;
        }
    }
    
    return UART_TX_OK;
}

/**
 * @brief  串口接收数据
 * @param  data: 接收数据缓冲区指针
 * @param  size: 要接收的数据长度
 * @param  timeout: 接收超时时间(ms)
 * @retval UART_RX_Status_t: 接收状态
 * @note   阻塞式接收，会等待接收完成或超时
 */
UART_RX_Status_t UART_ReceiveData(uint8_t* data, uint16_t size, uint32_t timeout)
{
    uint32_t start_time;
    uint16_t received_size = 0;
    uint16_t available_data;
    
    if (data == NULL || size == 0) {
        return UART_RX_ERROR;
    }
    
    start_time = HAL_GetTick();
    
    while (received_size < size) {
        /* 检查超时 */
        if (HAL_GetTick() - start_time > timeout) {
            return UART_RX_TIMEOUT_ERR;
        }
        
        /* 获取可用数据长度 */
        available_data = UART_GetRxDataLength();
        
        if (available_data > 0) {
            /* 计算本次可以读取的数据量 */
            uint16_t read_size = (available_data < (size - received_size)) ? 
                                 available_data : (size - received_size);
            
            /* 从接收缓冲区读取数据 */
            for (uint16_t i = 0; i < read_size; i++) {
                data[received_size + i] = uart_rx_buffer[rx_read_index];
                rx_read_index = (rx_read_index + 1) % UART_RX_BUFFER_SIZE;
            }
            
            received_size += read_size;
        }
        
        /* 短暂延时，避免过度占用CPU */
        HAL_Delay(1);
    }
    
    return UART_RX_OK;
}

/**
 * @brief  串口接收一行数据
 * @param  buffer: 接收缓冲区指针
 * @param  max_size: 缓冲区最大大小
 * @param  timeout: 接收超时时间(ms)
 * @retval UART_RX_Status_t: 接收状态
 * @note   接收直到遇到换行符或超时
 */
UART_RX_Status_t UART_ReceiveLine(char* buffer, uint16_t max_size, uint32_t timeout)
{
    uint32_t start_time;
    uint16_t received_size = 0;
    uint16_t available_data;
    uint8_t temp_data;
    
    if (buffer == NULL || max_size == 0) {
        return UART_RX_ERROR;
    }
    
    start_time = HAL_GetTick();
    
    while (received_size < max_size - 1) {
        /* 检查超时 */
        if (HAL_GetTick() - start_time > timeout) {
            buffer[received_size] = '\0';
            return UART_RX_TIMEOUT_ERR;
        }
        
        /* 获取可用数据长度 */
        available_data = UART_GetRxDataLength();
        
        if (available_data > 0) {
            /* 读取一个字符 */
            temp_data = uart_rx_buffer[rx_read_index];
            rx_read_index = (rx_read_index + 1) % UART_RX_BUFFER_SIZE;
            
            /* 检查是否为换行符 */
            if (temp_data == '\n' || temp_data == '\r') {
                buffer[received_size] = '\0';
                return UART_RX_OK;
            }
            
            /* 存储字符 */
            buffer[received_size] = temp_data;
            received_size++;
        }
        
        /* 短暂延时，避免过度占用CPU */
        HAL_Delay(1);
    }
    
    /* 缓冲区满，添加结束符 */
    buffer[received_size] = '\0';
    return UART_RX_OK;
}

/**
 * @brief  获取接收缓冲区中的数据长度
 * @param  None
 * @retval uint16_t: 缓冲区中的数据长度
 */
uint16_t UART_GetRxDataLength(void)
{
    return UART_CalculateDataLength(rx_read_index, rx_write_index, UART_RX_BUFFER_SIZE);
}

/**
 * @brief  清空接收缓冲区
 * @param  None
 * @retval None
 */
void UART_ClearRxBuffer(void)
{
    rx_read_index = rx_write_index;
    memset(uart_rx_buffer, 0, UART_RX_BUFFER_SIZE);
}

/**
 * @brief  串口发送单个字节
 * @param  byte: 要发送的字节
 * @retval None
 * @note   阻塞式发送，会等待发送完成
 */
void UART_SendByte(uint8_t byte)
{
    /* 等待上一次发送完成 */
    while (uart_tx_busy) {
        HAL_Delay(1);
    }
    
    /* 设置发送忙标志 */
    uart_tx_busy = 1;
    
    /* 发送数据 */
    HAL_UART_Transmit_IT(&huart1, &byte, 1);
    
    /* 等待发送完成 */
    while (uart_tx_busy) {
        HAL_Delay(1);
    }
}

/**
 * @brief  串口接收完成回调函数
 * @param  huart: UART句柄指针
 * @retval None
 * @note   由HAL库自动调用
 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1) {
        /* 更新写指针 */
        rx_write_index = (rx_write_index + 1) % UART_RX_BUFFER_SIZE;
        
        /* 检查缓冲区是否满 */
        if (rx_write_index == rx_read_index) {
            /* 缓冲区满，丢弃最旧的数据 */
            rx_read_index = (rx_read_index + 1) % UART_RX_BUFFER_SIZE;
        }
        
        /* 设置接收就绪标志 */
        uart_rx_ready = 1;
        
        /* 重新启动接收中断 */
        HAL_UART_Receive_IT(&huart1, &uart_rx_buffer[rx_write_index], 1);
    }
}

/**
 * @brief  串口发送完成回调函数
 * @param  huart: UART句柄指针
 * @retval None
 * @note   由HAL库自动调用
 */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1) {
        /* 清除发送忙标志 */
        uart_tx_busy = 0;
    }
}

/**
 * @brief  计算缓冲区中的数据长度
 * @param  read_index: 读指针
 * @param  write_index: 写指针
 * @param  buffer_size: 缓冲区大小
 * @retval uint16_t: 数据长度
 */
static uint16_t UART_CalculateDataLength(uint16_t read_index, uint16_t write_index, uint16_t buffer_size)
{
    if (write_index >= read_index) {
        return write_index - read_index;
    } else {
        return buffer_size - read_index + write_index;
    }
}

/**
 * @brief  计算缓冲区中的可用空间
 * @param  read_index: 读指针
 * @param  write_index: 写指针
 * @param  buffer_size: 缓冲区大小
 * @retval uint16_t: 可用空间大小
 */
static uint16_t UART_CalculateFreeSpace(uint16_t read_index, uint16_t write_index, uint16_t buffer_size)
{
    return buffer_size - UART_CalculateDataLength(read_index, write_index, buffer_size) - 1;
}

/* USER CODE END 0 */
